package com.ksd.quartz.task;

import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ksd.common.config.PlayControlConfig;
import com.ksd.common.enums.SynchContentStatusEnum;
import com.ksd.common.utils.DateUtils;
import com.ksd.common.utils.StringUtils;
import com.ksd.quartz.domain.SysJob;
import com.ksd.quartz.http.DRMHttpClient;
import com.ksd.quartz.http.NIOFileDownloader;
import com.ksd.quartz.service.ISysJobService;
import com.ksd.quartz.task.beans.SynchApkRequest;
import com.ksd.quartz.task.beans.SynchDataRequest;
import com.ksd.quartz.task.beans.SynchDataResponse;
import com.ksd.quartz.task.beans.SynchJarResponse;
import com.ksd.quartz.util.FileUtil;
import com.ksd.quartz.util.SystemTool;
import com.ksd.quartz.util.TaskConstans;
import com.ksd.quartz.util.UnzipUtility;
import com.ksd.system.domain.SysApkVersion;
import com.ksd.system.domain.SysBoard;
import com.ksd.system.domain.SysContentSynch;
import com.ksd.system.domain.SysSynchData;
import com.ksd.system.service.*;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * 向远程内容同步系统发送请求,获取远程最新的待同步内容
 */
@Component("synchContentServiceTask")
public class SynchContentServiceTask {

    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(SynchContentServiceTask.class);

    @Autowired
    private ISysContentSynchService sysContentSynchService;
    @Autowired
    private ISysSynchDataService sysSynchDataService;
    @Autowired
    private ISysJobService sysJobService;
    @Autowired
    private ISysOperLogService sysOperLogService;

    public void getContentInterface() throws SchedulerException {
        logger.info("向外网部署的政企内容同步系统接口查询是否有待同步的内容(电影/音乐)压缩包地址");

        //先通过接口将压缩包数据下载到本地服务上-->进入数据导入表记录中
        //解压
        //读取配置文件,分辨是电影内容还是音乐内容
        //入库--->批次记录
        SysContentSynch sysContentSynch = sysContentSynchService.selectSysContentSynchById(SysContentSynch.cloudSynchFlag);
        SynchDataRequest request = new SynchDataRequest();
        request.setOperatorKey(sysContentSynch.getValue1());

        String requestGson = JSONObject.toJSONString(request);

        String url = sysContentSynch.getValue2()+ TaskConstans.synchContentDataZipUrl;
        logger.info("[system-synchDataZip] SynchContentDataZipTask Interface url :" + url);
        logger.info("[system-synchDataZip] SynchContentDataZipTask Interface Request :" + requestGson);

        String response = DRMHttpClient.udrmHttpDoPost(url, requestGson);
        ObjectMapper mapperPage = new ObjectMapper();
        try {
            SynchDataResponse synchDataResponse = mapperPage.readValue(response, SynchDataResponse.class);
            logger.info("[system-synchDataZip] SynchContentDataZipTask Interface Response :" + synchDataResponse.toString());
            if (StringUtils.isNotNull(synchDataResponse)) {
                Integer status = synchDataResponse.getStatus();
                if (status == -1){
                    logger.info(synchDataResponse.getMessage());
                    sysOperLogService.insertOperlogApiError("向远程服务器做内容同步接口响应状态失败."+status);
                    return;
                }else{
//                    SysBoard sysBoard = sysBoardService.selectSysBoardById(SysBoard.serviceFileId);//将机顶盒升级包下载到服务器上,机顶盒能够直接放到到
                    String zipPath = synchDataResponse.getZipPath();//该文件地址需要能够通过服务器直接访问到,即在云服务器上已部署在nginx指定目录下
                    String zipName = synchDataResponse.getZipName();
                    SysSynchData sysSynchData = new SysSynchData();
                    sysSynchData.setUnzipPath(zipPath);
                    List<SysSynchData> synchDataList = sysSynchDataService.selectSysSynchDataList(sysSynchData);

                    String dataPath = File.separator+"playcontrol_data_zip"+File.separator+ DateUtils.dateTimeNow();
                    String downPath = PlayControlConfig.getDiskNginxRootPath()+ dataPath+File.separator+zipName;
                    String mappedPath = PlayControlConfig.getDiskMappingPath()+ dataPath+File.separator+zipName;
                    logger.info("待同步的内容数据更新下载到服务器地址:"+downPath);
                    sysOperLogService.insertOperlogApiSuccess("待同步的内容数据更新下载到服务器地址:"+downPath);
                    Boolean downFlag = false;

                    if (synchDataList.size() > 0) {
                        sysSynchData = synchDataList.get(0); //对比最新内容同步数据地址是否一致
//                        String statusSql = sysSynchData.getStatus();
//                        if (!sysSynchData.getCloudPath().equals(zipPath)){
                            logger.info("内容压缩包升级更新下载,将更新到服务地址:"+downPath);
                            sysOperLogService.insertOperlogApiSuccess("内容压缩包升级更新下载,将更新到服务地址:"+downPath);
                            //将该待同步的内容压缩包下载下来,同时需要下载到指定目录下,即该系统服务器的nginx指定目录下
                            try {
                                downFlag = NIOFileDownloader.downloadFile(zipPath, downPath);
                                if (downFlag){
                                    logger.info("内容压缩包文件下载成功:"+downPath);
                                    sysOperLogService.insertOperlogApiSuccess("内容压缩包文件下载成功:"+downPath);
                                    logger.info("待同步的压缩包更新映射到服务器的地址:"+mappedPath);
                                    sysOperLogService.insertOperlogApiSuccess("待同步的压缩包更新映射到服务器的地址:"+mappedPath);
                                    //同步升级信息

                                    sysSynchData.setUrl(mappedPath);
                                    sysSynchData.setCloudPath(zipPath);
                                    sysSynchData.setStatus(SynchContentStatusEnum.extract_ing.getCode()); //开始进入解压缩步骤
                                    sysSynchDataService.updateSysSynchData(sysSynchData);
                                }else{
                                    logger.error("内容压缩包文件下载失败,"+downPath);
                                    sysOperLogService.insertOperlogApiError("内容压缩包文件下载失败,"+downPath);
                                    sysSynchData.setStatus(SynchContentStatusEnum.down_failed.getCode());
                                    sysSynchDataService.updateSysSynchData(sysSynchData);
                                }
                            } catch (IOException e) {
                                sysSynchData.setStatus(SynchContentStatusEnum.down_failed.getCode());
                                sysSynchDataService.updateSysSynchData(sysSynchData);
                                logger.error("内容压缩包文件下载失败: " + e.getMessage()+" ,待下载的机顶盒版本地址:"+zipPath);
                                sysOperLogService.insertOperlogApiError("内容压缩包文件下载失败: " + e.getMessage()+" ,待下载的机顶盒版本地址:"+zipPath);
                            }
//                        }else{
//                            logger.info("内容压缩包:"+zipPath+"已与云服务同步,无需下载同步");
//                        }
                    }else {
                        logger.info("内容压缩包:"+zipPath+",第一次同步,将压缩包更新到服务地址:"+downPath);
                        sysOperLogService.insertOperlogApiSuccess("内容压缩包:"+zipPath+",第一次同步,将压缩包更新到服务地址:"+downPath);
                        //同步内容信息
                        sysSynchData.setCloudPath(zipPath);
                        sysSynchData.setUrl(mappedPath);
                        sysSynchData.setUpdateTime(new Date());
                        sysSynchData.setCreateTime(new Date());
                        sysSynchData.setStatus(SynchContentStatusEnum.extract_ing.getCode());//开始进行解压缩步骤
                        sysSynchDataService.insertSysSynchData(sysSynchData);
                        try {
                            downFlag = NIOFileDownloader.downloadFile(zipPath, downPath);
                            if (downFlag){
                                logger.info("内容压缩包文件下载成功:"+downPath);
                                sysOperLogService.insertOperlogApiSuccess("内容压缩包文件下载成功:"+downPath);
                                logger.info("待同步的内容压缩包更新映射到服务器的地址:"+mappedPath);
                                sysOperLogService.insertOperlogApiSuccess("待同步的内容压缩包更新映射到服务器的地址:"+mappedPath);
                            }else{
                                logger.error("内容压缩包文件下载失败,"+downPath);
                                sysOperLogService.insertOperlogApiError("内容压缩包文件下载失败,"+downPath);
                                sysSynchData.setStatus(SynchContentStatusEnum.down_failed.getCode());//文件下载失败
                                sysSynchDataService.updateSysSynchData(sysSynchData);
                            }
                        } catch (IOException e) {
                            sysSynchData.setStatus(SynchContentStatusEnum.down_failed.getCode());//文件下载失败
                            sysSynchDataService.updateSysSynchData(sysSynchData);
                            logger.error("待同步的内容压缩包文件下载失败: " + e.getMessage()+" ,待下载同步的内容压缩包地址:"+zipPath);
                            sysOperLogService.insertOperlogApiError("待同步的内容压缩包文件下载失败: " + e.getMessage()+" ,待下载同步的内容压缩包地址:"+zipPath);
                        }
                    }

                    if (downFlag){
                        logger.info("待同步的内容数据压缩包已下载成功:"+downPath+", 开始进行解压缩、入库处理");
                        sysOperLogService.insertOperlogApiSuccess("待同步的内容数据压缩包已下载成功:"+downPath+", 开始进行解压缩、入库处理");
                        logger.info("压缩包上传到服务器的路径filePath:"+downPath);

                        String synchDataPath = File.separator+"playcontroller_synch_data"+File.separator+ DateUtils.dateTimeNow();
                        String synchFilePath = PlayControlConfig.getDiskNginxRootPath()+  synchDataPath; //服务器文件实际存储地址
                        sysSynchData.setUnzipPath(synchFilePath);
                        sysSynchDataService.updateSysSynchData(sysSynchData);
                        try {
                            sysSynchData.setUpdateTime(new Date());
                            UnzipUtility.unzip(downPath,synchFilePath);
                            //解压缩完成之后,另开启一个线程进行文件解压缩

                        } catch (IOException e) {
                            sysSynchData.setStatus(SynchContentStatusEnum.extract_failed.getCode()); //解压失败
                            sysSynchData.setUpdateTime(new Date());
                            sysSynchDataService.updateSysSynchData(sysSynchData);
                            throw new RuntimeException(e);
                        }
                        sysSynchData.setStatus(SynchContentStatusEnum.wait.getCode()); //等待同步
                        sysSynchDataService.updateSysSynchData(sysSynchData);
                        logger.info("解析上传目录的文件的所有文件,进行数据录入,可能存在电影,音乐");
                    }
                }
            }else{
                logger.info("系统向远程服务器做内容同步接口响应为空");
                sysOperLogService.insertOperlogApiError("系统向远程服务器做内容同步接口响应为空");
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error(e.getMessage());
        }

        SysJob sysJob = sysJobService.selectJobById(SysJob.synchZipContentTaskId);
        if (StringUtils.isNotNull(sysJob)){
            sysJobService.run(sysJob);
        }
        logger.info("将内容压缩包同步到本地服务器结束===========================================end");


    }

}
